# -*- coding: utf-8 -*-
# @author: 龙非池
from __future__ import unicode_literals

import hashlib
import json
import logging
import os
import random
import time
import traceback
import urllib2

from django.http import HttpResponse, HttpResponseBadRequest
from django.utils.encoding import smart_str
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_exempt
from wenlincms.utils.cache import cache_installed, _hashed_key, cache_get, cache_set

from mainsys.settings import STATIC_URL, STATIC_ROOT
from mainsys.settings import elasticsearch_host
from wlapps.utils import xmltodict
from wlmodels.company.models import elasticsearch_index
from . import WECHAT_FUWU

add_log = logging.getLogger('error')
search_log = logging.getLogger('search')


# 接收用户的消息或微信官方的回调消息
@csrf_exempt
@never_cache
def wechat_main(request):
    # 如果是GET方法，校验消息的真实性
    if request.method == 'GET':
        try:
            signature = request.GET.get("signature")
            timestamp = request.GET.get("timestamp")
            nonce = request.GET.get("nonce")
            echostr = request.GET.get("echostr")
            token = WECHAT_FUWU["token"]

            if signature and timestamp and nonce and echostr:
                sortlist = [token, timestamp, nonce]
                sortlist.sort()
                sha = hashlib.sha1()
                sha.update("".join(sortlist))
                sha_str = sha.hexdigest()
                if sha_str == signature:
                    return HttpResponse(echostr)
                else:
                    return HttpResponseBadRequest('Verify Failed')
            else:
                return HttpResponseBadRequest('Verify Failed')
        except Exception:
            add_log.info("Wechat Verify Failed: \n%s\n\n.", str(traceback.format_exc()))
            return HttpResponse('')

    # 如果是POST方法，提取xml数据
    else:
        xml_str = smart_str(request.body)
        # 解析本次请求的 XML 数据
        try:
            request_xml = xmltodict.parse(xml_str)
            request_dict = request_xml["xml"]
            msgtype = request_dict["MsgType"]
            touser = request_dict["FromUserName"]

            # 如果是文本、语音消息
            if msgtype in ["text", "voice"]:
                if msgtype == "voice":
                    content = request_dict["Recognition"].replace('！', '').replace('。', '')
                else:
                    content = request_dict["Content"]
                res_text = response_search(touser, content, mtype=msgtype)
                return HttpResponse(res_text, content_type='text/xml')

            # 如果是事件消息
            elif msgtype == "event":
                res_text = ''
                # 关注事件
                if request_dict["Event"] == "subscribe":
                    res_content = """欢迎关注企业大数据"""
                    res_text = response_text(touser, res_content)
                # 点击查企业
                elif request_dict["Event"] == "CLICK" and request_dict["EventKey"] == "entsearch":
                    res_content = """在微信中切换菜单为输入框，输入关键词，点击您想关注的企业，我们将为您推送该企业相关的风险监控信息（支持语音输入哦）。"""
                    res_text = response_text(touser, res_content)
                return HttpResponse(res_text, content_type='text/xml')

            else:
                return HttpResponse('')
        except Exception:
            add_log.info("Received Invalid XML Data: %s\n%s\n\n.", xml_str, str(traceback.format_exc()))
            return HttpResponse('')


# 获得token
def get_access_token():
    # 先查询缓存
    time_out = 3600
    cache_key = _hashed_key("wechataccesstoken")
    if cache_installed():
        access_token = cache_get(cache_key)
        if access_token:
            return access_token
        else:
            access_token = get_access_token_from_url()
            cache_set(cache_key, access_token, timeout=time_out)
            return access_token
    else:
        access_token = get_access_token_from_url()
        cache_set(cache_key, access_token, timeout=time_out)
        return access_token


# 从微信官方获取token
def get_access_token_from_url():
    the_url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' + WECHAT_FUWU["APP_KEY"] \
              + '&secret=' + WECHAT_FUWU["APP_SECRET"]
    req = urllib2.Request(the_url)
    res = urllib2.urlopen(req)
    res_data = res.read()
    res.close()
    res_dict = json.loads(res_data)
    access_token = res_dict["access_token"]
    return access_token


# 回复文本消息
def response_text(touser, content):
    temp_data = """
        <xml>
            <ToUserName><![CDATA[%s]]></ToUserName>
            <FromUserName><![CDATA[%s]]></FromUserName>
            <CreateTime>%s</CreateTime>
            <MsgType><![CDATA[text]]></MsgType>
            <Content><![CDATA[%s]]></Content>
        </xml>
        """
    xml_data = temp_data % (touser, WECHAT_FUWU["from_username"], str(int(time.time())), content)
    return xml_data


# 自动回复企业、机构和供需的搜索结果，图文消息
def response_search(touser, content, mtype=None):
    try:
        res_content = "抱歉，没有查询到相关企业或机构，请缩减关键词重新搜索"
        if mtype == "voice":
            res_content = "您的语音识别为：" + content + "\n没有查询到相关企业或机构，请重新输入或更换关键词进行重新搜索"
        temp_data_first = """
                <xml>
                    <ToUserName><![CDATA[%s]]></ToUserName>
                    <FromUserName><![CDATA[%s]]></FromUserName>
                    <CreateTime>%s</CreateTime>
                    <MsgType><![CDATA[news]]></MsgType>
                    <ArticleCount>%s</ArticleCount>
                    <Articles>
                """
        temp_data_end = """
                    </Articles>
                </xml>
                """
        temp_item = """
                <item>
                    <Title><![CDATA[%s]]></Title>
                    <Description><![CDATA[%s]]></Description>
                    <PicUrl><![CDATA[%s]]></PicUrl>
                    <Url><![CDATA[%s]]></Url>
                </item>
                """
        # 下面开始搜索
        content = content.strip()
        search_log.info("%s from wechat searched org: %s", touser, content)

        entresult = []
        if elasticsearch_host and len(content) > 1:
            q_dict = {
                "query": {
                    "match_phrase": {"ENTNAME": content}
                },
                "terminate_after": 5
            }
            q_url = elasticsearch_host + elasticsearch_index["company"] + "_search"
            q_json = json.dumps(q_dict).encode('utf8')
            req = urllib2.Request(url=q_url, data=q_json)
            res = urllib2.urlopen(req, timeout=60)
            res_data = res.read()
            res.close()
            res_dict = json.loads(res_data)

            if res_dict["hits"]["hits"]:
                for resobj in res_dict["hits"]["hits"]:
                    entresult.append({"ENTNAME": resobj["_source"]["ENTNAME"].split("。")[0]})
        entresult = entresult[:6]
        if len(content) and len(entresult):
            # 下面开始组织xml回复内容
            total_count = str(len(entresult))
            count_flag = 0
            temp_data_item = ''
            for obj in entresult:
                t_title = obj["ENTNAME"]
                t_url = "http://saas.elecredit.com/"
                t_des = '点击关注 %s' % obj["ENTNAME"]
                # 下面生成随机图片，如果是第一张，用大图
                if count_flag == 0:
                    pic_path = random_pic(ptype='first')
                else:
                    pic_path = random_pic()
                if STATIC_URL.startswith("http://"):
                    t_pic = STATIC_URL + pic_path
                else:
                    t_pic = "http://saas.elecredit.com" + STATIC_URL + pic_path
                temp_data_item += temp_item % (t_title, t_des, t_pic, t_url)
                count_flag += 1
            temp_data_first = temp_data_first % (touser, WECHAT_FUWU["from_username"], str(int(time.time())), total_count)
            xml_data = temp_data_first + temp_data_item + temp_data_end
        # 没有找到相关内容，回复提示文本
        else:
            xml_data = response_text(touser, res_content)
        return xml_data
    except Exception:
        add_log.info("Wechat Search Error: %s\n%s\n\n.", content, str(traceback.format_exc()))
        return response_text(touser, "系统太累啦，请稍后再试")


# 生成微信消息专用的随机图片
def random_pic(ptype=None):
    path = "element/saas/img/wechat" + os.sep
    if ptype == 'first':
        path = "element/saas/img/wechat_0" + os.sep
    path_root = os.path.join(STATIC_ROOT, path.replace("/", os.sep))
    files = os.listdir(path_root)
    pic_path = 'element/saas/img/wechat/1.jpg'
    if ptype == 'first':
        pic_path = 'element/saas/img/wechat_0/1.jpg'
    if len(files):
        i = random.randint(0, len(files) - 1)
        pic_path = path + files[i]
    return pic_path


# 自定义菜单的备份，需要转换为json
menu = {
    "button": [
        {
            "type": "click",
            "name": "关注企业",
            "key": "entsearch"
        },
        {
            "name": "产品介绍",
            "sub_button": [
                {
                    "type": "view",
                    "name": "SAAS平台",
                    "url": "http://saas.elecredit.com/",
                    "sub_button": []
                },
                {
                    "type": "view",
                    "name": "数据集市",
                    "url": "http://www.elecredit.com/",
                    "sub_button": []
                }
            ]
        },
        {
            "type": "view",
            "name": "关于我们",
            "url": "http://mp.weixin.qq.com/s/WSCpianPf2dgJyOlb1Gmag",
            "sub_button": []
        }
    ]
}
